﻿using Infrastructure;
using Infrastructure.Attribute;
using IP2Region.Ex.Models;
using Newtonsoft.Json.Linq;
using SqlSugar;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using ZR.DataCollection.Model;
using ZR.DataCollection.OperationCore.AbstractFactory;
using ZR.DataCollection.OperationCore.OperationEnum;
using ZR.DataCollection.SingleParameter;
using ZR.Model.Models.ProductionControl;
using ZR.Service.Business.IBusinessService;
using ZR.Service.IService.ProductionControl;
using ZR.ServiceCore.Services;
using static System.Collections.Specialized.BitVector32;

namespace ZR.DataCollection.OperationCore.OperationHelper
{
    public class OperationInfoBase : BaseOperationModel
    {
        private readonly IOperationPointConfigService _operationPointService = App.GetRequiredService<IOperationPointConfigService>();
        private readonly IStationWorkInfoService _stationWorkInfoService = App.GetRequiredService<IStationWorkInfoService>();
        protected int _opertationType;
        protected string _stationType;

        public override event Action<string> Event_Notification;

        public OperationInfoBase(int operationType, string stationType)
        {
            _opertationType = Convert.ToInt32((OperationTypeEnum)operationType);
            _stationType = stationType;
        }

        public virtual Dictionary<int, List<OperationPointConfig>> CurrentCruxPoint(string line, string productionType, int itemNo)
        {
            return _operationPointService.ListByOpAndType(_stationType, line, productionType, _opertationType, itemNo);
        }

        /// <summary>
        /// 操作Logic,可重写
        /// </summary>
        /// <param name="imp"></param>
        public override void WorkDetail(ImpParameter imp)
        {
            DataDock? dataDock = imp.objectParam as DataDock;
            Dictionary<int, List<OperationPointConfig>> keyValuePairs = CurrentCruxPoint(dataDock.LineCode, dataDock.ProductType, dataDock.ItemNo);
            SpotHandle(imp, keyValuePairs);
        }

        public override void SignalReset(ImpParameter imp)
        {
            DataDock? dataDock = imp.objectParam as DataDock;
            Dictionary<int, List<OperationPointConfig>> keyValuePairs = CurrentCruxPoint(dataDock.LineCode, dataDock.ProductType, dataDock.ItemNo);
            if (keyValuePairs.ContainsKey(2))
            {
                foreach (var operationPointInfo in keyValuePairs[2])
                {
                    imp.PLCDetail.WriteAddress(operationPointInfo.ItemAddress, Convert.ToInt16(0));
                }
            }
        }

        public virtual void SpotHandle(ImpParameter parameter, Dictionary<int, List<OperationPointConfig>> SpotGroup)
        {
            foreach (var SpotInfo in SpotGroup)
            {
                switch (SpotInfo.Key)
                {
                    case (int)DataOperateEnum.Read:
                        break;

                    case (int)DataOperateEnum.Write:
                        break;

                    case (int)DataOperateEnum.Verify:
                        break;

                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// 过站开始数据
        /// </summary>
        /// <param name="parameter"></param>
        public virtual async Task<int> OverStationStart(DataDock dataDock, OrderDetailInfo orderDetail, string productId, string? procedurNo = "")
        {
            StationWorkInfo stationWorkStart = new StationWorkInfo();
            stationWorkStart.LineCode = dataDock.LineCode;
            stationWorkStart.StationCode = dataDock.StationCode;
            stationWorkStart.ProductName = orderDetail.ProductName;
            stationWorkStart.ShiftName = "morning";
            stationWorkStart.OrderCode = orderDetail.OrderCode;
            stationWorkStart.ProductId = productId;
            stationWorkStart.ProductType = orderDetail.ProductType;
            stationWorkStart.WorkStartTime = DateTime.Now;
            stationWorkStart.ProcedureNo = procedurNo;
            return await _stationWorkInfoService.InsertAsync(stationWorkStart);
        }

        public virtual async Task<bool> OverStationEnd(DataDock dataDock, string productId, string result)
        {
            StationWorkInfo workInfo = await _stationWorkInfoService
                .QueryByClauseAsync(qbc => qbc.ProductId.Equals(productId) && qbc.StationCode.Equals(dataDock.StationCode) && qbc.LineCode.Equals(dataDock.LineCode));
            workInfo.WorkEndTime = DateTime.Now;
            TimeSpan timeSpan = new TimeSpan(workInfo.WorkEndTime.Ticks - workInfo.WorkStartTime.Ticks);
            workInfo.WorkTempo = (int?)timeSpan.TotalSeconds;
            workInfo.WorkResult = result;
            return await _stationWorkInfoService.InsertOrUpdateAsync(workInfo);
        }
    }
}